home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-02 | 51.2 KB | 1,702 lines |
- Newsgroups: comp.sources.misc
- subject: v13i018: PD make V1.6 (Part 1 of 2)
- From: greggy@zebra.UUCP (Greg Yachuk)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 13, Issue 18
- Submitted-by: greggy@zebra.UUCP (Greg Yachuk)
- Archive-name: make1.6/part01
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: README MANIFEST decl.h make.c make.doc
- # Wrapped by greggy@etude on Thu May 31 10:55:30 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(5819 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XMake Version 1.6 90-02-08
- X
- XThis is the source for a public domain version of make. It is very
- Xsimilar to the `make' provided on Sun systems. It is compiled with
- XMicrosoft C (5.1) and runs on PCDOS 3.3. It also compiles and runs on
- XBSD 4.2 Unix.
- X
- XMany thanks to Dr. T. Andrews (uunet!cdin-1!cdis-1!tanner)
- X Arend van den Brug (arend@philmds@philnl@mcvax)
- X Jeff Fried (jfried@informix.com)
- X Brian Wilson (island!sun!grenada!dr_unix)
- X Kirk Bailey (bailey@mist.cs.orst)
- X
- Xfor pointing out problems and improvements.
- X
- XI have included a makefile and a (rudimentary) default.mk for BSD Unix.
- XUpdates, additions and corrections are welcomed. The shar distribution
- Xhas the filenames reversed from the ZOO distribution:
- X
- X ZOO distribution shar distribution
- X ---------------------------- --------------------------
- X makefile makefile.bsd makefile.dos makefile
- X default.mk default.bsd default.dos default.mk
- X
- X
- XI'm assuming that the ZOO is used on DOS and the shar on Unix. If what
- Xyou got is not appropriate, rename the appropriate files and make. For
- Xexample, if you got the DOS version on a Unix system:
- X
- X mv makefile makefile.dos
- X mv makefile.bsd makefile
- X mv default.mk default.dos
- X mv default.bsd default.mk
- X make
- X
- XAlternatively, you can (probably) just use this following command:
- X
- X make -r -f default.bsd -f makefile.bsd
- X===========================================================================
- XThis is version 1.6. Here are the changes from 1.5 to 1.6:
- X
- X accept and ignore the -b option for backwards compatibility.
- X
- X accept and ignore the -- option for compatibility with SCO Xenix.
- X
- X set up spawnvp() so that the wait() call works on non-BSD Unix.
- X
- X translate "$$" to "$" when doing macro expansion.
- X
- X set "$?" to the set of dependents younger than the current target.
- X
- X support GnuMake's -W (What If) switch.
- X
- X strip quotes from around arguments before spawning a command (DOS).
- X
- X emulate inline-stdin redirection ("<<") on DOS by collecting the
- X following commands into a temporary file and placing the filename
- X on the command line.
- X
- X===========================================================================
- XThere is a version 1.4 that was submitted to comp.binaries.ibm.pc by
- XArend van den Brug. I have incorporated many of the changes into my
- Xversion and called it 1.5. These are the changes from 1.3 to 1.5:
- X
- X support the -k, -S and -q options (see make.man).
- X
- X correctly support the $(MAKE) macro.
- X
- X allow target lines to end with a semi-colon and a command.
- X
- X corrected bugs when allocated strings are over-run.
- X
- X added "*?[]()&" to the list of characters that force the use of the
- X shell on Unix.
- X
- X===========================================================================
- XThese are the changes from 1.2 to 1.3:
- X
- X don't append shell command lines when encountering multiple targets
- X of the same name. if this is a *special* target (e.g. .c.obj),
- X just override. otherwise exit with an error.
- X
- X flush output before executing the command, so the output comes out
- X in the right order when redirecting stdout to a file.
- X
- X if a file is supposedly built, but does not exists, use current
- X time.
- X
- X exit with an error if a target line does not have a ':'.
- X
- X don't force a space after "include" in case TAB is used.
- X
- X D and F modifiers for Directory and Filename of $@, $<, $*.
- X
- X use a dependent file for an implicit rule, if possible.
- X
- X allow Makefile as well as makefile, for Unix.
- X
- X always print statements when using -n, even if they start with @.
- X
- X backquote (`) will force use of a shell, in Unix.
- X
- X===========================================================================
- XThese are the changes from 1.1 to 1.2:
- X
- X ensure command line macros override makefile macros, even as
- X makefiles are being read in.
- X
- X support time checks correctly on MSDOS directories.
- X
- X use MAKEFLAGS macro, and set it up for subordinate makes.
- X
- X import environment variables and support -e flag.
- X
- X handle `-f -' (i.e. makefile from stdin) correctly.
- X
- X clean up some potential NULL pointer dereferences.
- X
- X correct errors in handling nested makes.
- X
- X modify tokenizing routine to correctly handle trailing separators.
- X
- X the documentation has been re-written
- X
- X===========================================================================
- XThese are the changes from 1.0 to 1.1:
- X
- X modify prerequisite list handling to correctly allow a target to
- X appear on multiple target lines.
- X
- X
- XThere is a short story which goes with this offering. Sometime early in
- X1988, someone (possibly Dan Grayson) posted copyrighted source for a
- X`make' to Usenet. I used it and modified it somewhat, and then lost my
- Xhard disk. Having found this program to be very useful, I set about
- Xrewriting it from my recollection of the source that I had seen. I have
- Xasked Rahul (moderator of comp.binaries.ibm.pc) if he could trace the
- Xoriginal submitter, and have also posted a note to the net in c.b.i.p.d,
- Xtrying to locate this person. So far, no trace has been found. I
- Xreally would like to show this source to him (and hopefully have him
- Xagree that it is not the same as his).
- X
- XI have based my algorithms on this previous source code. Algorithms are
- Xnot copyrightable, so I feel that I have not infringed upon anyone's
- Xrights. Also, I have acted in good faith trying to trace this person.
- XI hope that recipients of this code feel the same. I am releasing this
- Xinto the public domain. You may do anything you wish with it, even
- Xcopyright it yourself and try to sell it as your own. Good luck, and
- Xhave fun.
- X
- X -greg
- X
- XGreg Yachuk Informix Software Inc., Menlo Park, CA 92025
- Xgreggy@informix.com | {uunet,pyramid}!infmx!greggy (415) 926-6300
- END_OF_FILE
- if test 5819 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(547 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X----------------------------------------------------------
- X README 1
- X MANIFEST 1 This shipping list
- X build.c 2
- X decl.h 1
- X default.mk 2
- X default.msc 2
- X make.c 1
- X make.doc 1
- X make.h 2
- X makefile 2
- X makefile.msc 2
- X parse.c 2
- X tstring.c 2
- X tstring.h 2
- END_OF_FILE
- if test 547 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'decl.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'decl.h'\"
- else
- echo shar: Extracting \"'decl.h'\" \(2877 characters\)
- sed "s/^X//" >'decl.h' <<'END_OF_FILE'
- X/*
- X * decl.h
- X *
- X * 88-10-01 v1.0 created by greg yachuk, placed in the public domain
- X * 88-10-06 v1.1 changed prerequisite list handling
- X * 88-11-11 v1.2 fixed some bugs and added environment variables
- X * 89-07-12 v1.3 stop appending shell commands, and flush output
- X * 89-08-01 v1.4 AB lots of new options and code
- X * 89-10-30 v1.5 -f -S -q options, took some changes from v1.4
- X * 90-04-18 v1.6 -b -- -W options, emulate <<, non-BSD cleanup
- X */
- X
- X#ifdef __STDC__
- Xextern int main(int argc, char **argv);
- Xextern int make_args(int argc, char **argv);
- Xextern char **grow_list(char **list, int *len);
- Xextern FILE *fopenp(char *fname, char *type);
- Xextern int make(char *targname, int worry);
- Xextern int default_rule(char *targname, struct targnode * targetp, int worry, int mustbuild);
- Xextern char *get_preqname(struct targnode * targp, char *suffix, char *basename);
- Xextern int add_metas(char *basename, char *preqname, char *targname);
- Xextern int split_meta(char *sym, char *name);
- Xextern int touch_file(char *targname);
- Xextern int display_prereq(char *targname, long targtime, char *preqname, long preqtime);
- Xextern long file_time(char *fname, int built);
- Xextern int usage(void);
- Xextern int build(struct shellnode * *shellp);
- Xextern char *shellinput(struct shellnode * **shellp, char *eof);
- Xextern int new_make(char **argv);
- Xextern int parse(FILE * fd);
- Xextern int link_targs(struct targnode * *targs, struct filenode * *preqs, struct shellnode * *shells);
- Xextern int add_macro(char *input, int scmd);
- Xextern int add_symbol(char *name, char *value, int scmd);
- Xextern struct symnode *get_symbol(char *name, int scmd);
- Xextern struct symnode *dup_symbol(struct symnode * sp, char *svalue);
- Xextern struct targnode *add_target(char *name);
- Xextern struct targnode *hash_target(char *name, unsigned short *maskp);
- Xextern struct filenode *add_file(char *name);
- Xextern struct filenode *hash_file(char *name, unsigned short *maskp);
- Xextern char **append_node(char **node, char **adds, int size);
- Xextern struct shellnode *add_shell(char *input);
- Xextern char *breakout(char *input);
- X#else
- Xextern int main();
- Xextern int make_args();
- Xextern char **grow_list();
- Xextern FILE *fopenp();
- Xextern int make();
- Xextern int default_rule();
- Xextern char *get_preqname();
- Xextern int add_metas();
- Xextern int split_meta();
- Xextern int touch_file();
- Xextern int display_prereq();
- Xextern long file_time();
- Xextern int usage();
- Xextern int build();
- Xextern char *shellinput();
- Xextern int new_make();
- Xextern int parse();
- Xextern int link_targs();
- Xextern int add_macro();
- Xextern int add_symbol();
- Xextern struct symnode *get_symbol();
- Xextern struct symnode *dup_symbol();
- Xextern struct targnode *add_target();
- Xextern struct targnode *hash_target();
- Xextern struct filenode *add_file();
- Xextern struct filenode *hash_file();
- Xextern char **append_node();
- Xextern struct shellnode *add_shell();
- Xextern char *breakout();
- X#endif
- END_OF_FILE
- if test 2877 -ne `wc -c <'decl.h'`; then
- echo shar: \"'decl.h'\" unpacked with wrong size!
- fi
- # end of 'decl.h'
- fi
- if test -f 'make.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'make.c'\"
- else
- echo shar: Extracting \"'make.c'\" \(18624 characters\)
- sed "s/^X//" >'make.c' <<'END_OF_FILE'
- X/*
- X * make.c An imitation of the Unix MAKE facility
- X *
- X * 88-10-01 v1.0 created by greg yachuk, placed in the public domain
- X * 88-10-06 v1.1 changed prerequisite list handling
- X * 88-11-11 v1.2 fixed some bugs and added environment variables
- X * 89-07-12 v1.3 stop appending shell commands, and flush output
- X * 89-08-01 v1.4 AB lots of new options and code
- X * 89-10-30 v1.5 -f -S -q options, took some changes from v1.4
- X * 90-04-18 v1.6 -b -- -W options, emulate <<, non-BSD cleanup
- X */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <fcntl.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <time.h>
- X#ifdef MSDOS
- X#include <stdlib.h>
- X#endif
- X
- X#include "make.h"
- X#include "tstring.h"
- X#include "decl.h"
- X
- X
- Xtargptr target_list = NULL; /* list of target nodes */
- Xfileptr file_list = NULL; /* list of file nodes */
- Xsymptr symbol_list = NULL; /* list of symbol nodes */
- Xshellptr shell_list = NULL; /* list of shell nodes */
- X
- Xchar **shell_cmds = NULL; /* commands which force a SHELL */
- X
- Xint make_level = 0; /* for counting new_make()'s */
- X
- Xtargptr first_targ = NULL; /* first target, in case nothing explicit */
- Xtargptr suffix_targ = NULL; /* .SUFFIXES target pointer */
- X
- Xchar **tlist = NULL; /* command line targets */
- Xchar **flist = NULL; /* command line make files */
- Xchar **mlist = NULL; /* command line macros */
- X
- Xint tmax = 0; /* max size of tlist */
- Xint fmax = 0; /* max size of flist */
- Xint mmax = 0; /* max size of mlist */
- X
- Xoptnode opts; /* all the options */
- Xint readdef = 1; /* -r option */
- Xint dispcount = 0; /* used for -D option */
- X
- Xlong now; /* time at startup */
- Xchar *makeflags; /* value to update the MAKEFLAGS macro with */
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int i;
- X targptr targp;
- X int mk;
- X symptr symp;
- X char *envp;
- X char **envv;
- X
- X /* initialize the various global lists */
- X
- X opts.depend = 0;
- X dispcount = 0;
- X
- X target_list = NULL;
- X file_list = NULL;
- X shell_list = NULL;
- X /* don't set symbol_list to NULL, or recursive makes won't work */
- X
- X /* allocate space for command line targets, files and macros */
- X
- X tlist = grow_list(NULL, &tmax);
- X flist = grow_list(NULL, &fmax);
- X mlist = grow_list(NULL, &mmax);
- X
- X /* process MAKEFLAGS environment variable, first */
- X
- X symp = get_symbol("MAKEFLAGS", 0);
- X if (symp->svalue != NULL)
- X {
- X /* chop up the MAKEFLAGS and feed them to to make_args() */
- X
- X envp = tstrcpy(symp->svalue);
- X envv = tokenize(envp);
- X for (i = 0; envv[i] != NULL; i++);
- X make_args(i, envv);
- X
- X /* free the vector of pointers, and the string itself, */
- X /* since you cannot have macros, targets or makefiles */
- X /* in the MAKEFLAGS macro. */
- X
- X tfree(envv);
- X tfree(envp);
- X tfree(makeflags); /* ignore this, since we just read it */
- X }
- X
- X make_args(--argc, ++argv); /* process command line options */
- X
- X add_macro(makeflags, 0);/* update the MAKEFLAGS macro */
- X tfree(makeflags);
- X
- X /* add command line macros, so they DON'T get overridden */
- X
- X for (i = 0; mlist[i] != NULL; i++)
- X add_macro(mlist[i], 1);
- X
- X tfree(mlist); /* all done with macros */
- X
- X if (opts.query) /* -q never executes anything */
- X opts.noexec = 1;
- X
- X if (opts.noexec)
- X opts.touch = 0; /* -n never touches */
- X
- X if (dispcount > 1) /* display `default.mk' on -DD */
- X opts.display = 1;
- X
- X first_targ = NULL; /* used in parse() */
- X
- X if (readdef) /* read in `default.mk' */
- X parse(fopenp(MAKEINI, "r"));
- X
- X if (dispcount > 0) /* display makefile's on -D */
- X opts.display = 1;
- X
- X first_targ = NULL; /* get first target in `makefile' */
- X
- X /* parse the makefiles given on command line */
- X for (i = 0; flist[i] != NULL; i++)
- X {
- X parse(equal(flist[i], "-") ? fdopen(dup(fileno(stdin)), "r")
- X : fopen(flist[i], "r"));
- X }
- X
- X /* no makefiles specified, so use "makefile" or "Makefile" */
- X if (i == 0)
- X {
- X if (parse(fopen("makefile", "r")) == 0)
- X {
- X#ifndef MSDOS
- X parse(fopen("Makefile", "r"));
- X#endif
- X }
- X }
- X
- X tfree(flist); /* all done with makefile's */
- X
- X /* find the current value of the $(MAKE) macro */
- X symp = get_symbol("MAKE", 0);
- X opts.make = (symp->svalue == NULL) ? "make" : symp->svalue;
- X
- X /* get list of commands which will force usage of SHELL */
- X symp = get_symbol("SHELLCMD", 0);
- X shell_cmds = (symp->svalue) ? tokenize(tstrcpy(symp->svalue)) : NULL;
- X
- X if ((targp = get_target(".INIT")) != NULL)
- X build(targp->tshell); /* process the .INIT rule */
- X
- X mk = 0;
- X
- X for (i = 0; tlist[i] != NULL; i++)
- X {
- X /* process command line arguments */
- X mk |= (make(tlist[i], 1) > 0) ? 1 : 0;
- X }
- X
- X tfree(tlist); /* all done with targets */
- X
- X /* if no targets specified, make the first one */
- X if (i == 0 && first_targ)
- X mk |= (make(first_targ->tfile->fname, 1) > 0) ? 1 : 0;
- X
- X if ((targp = get_target(".DONE")) != NULL)
- X build(targp->tshell); /* process the .DONE rule */
- X
- X /* all done with the shell commands, so clean up */
- X if (shell_cmds)
- X {
- X if (*shell_cmds)
- X tfree(*shell_cmds);
- X tfree(shell_cmds);
- X }
- X
- X return (mk & opts.query); /* not exit(); see new_make() */
- X}
- X
- X
- X/*
- X * make_args - process the command line arguments
- X */
- Xmake_args(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int tlen;
- X int flen;
- X int mlen;
- X int no_k = 0; /* override the -k option */
- X char *tmf;
- X int addflag;
- X fileptr fp;
- X
- X now = time(NULL); /* get current date & time */
- X
- X makeflags = tstrcpy("MAKEFLAGS+=");
- X
- X tlen = flen = mlen = 0;
- X
- X for (; argc != 0; ++argv, --argc)
- X {
- X if (**argv != '-')
- X {
- X /* doesn't start with '-'; must be macro or target */
- X
- X if (strchr(*argv, '='))
- X { /* store as a macro */
- X if (mlen == mmax)
- X mlist = grow_list(mlist, &mmax);
- X mlist[mlen++] = *argv;
- X }
- X else
- X { /* store as a target */
- X if (tlen == tmax)
- X tlist = grow_list(tlist, &tmax);
- X tlist[tlen++] = *argv;
- X }
- X continue;
- X }
- X
- X /* must be an option */
- X
- X tmf = tstrcat(makeflags, *argv);
- X
- X while (*argv && *++*argv)
- X {
- X addflag = 1; /* add to MAKEFLAGS */
- X switch (**argv)
- X {
- X case 'b': /* backwards compatibility */
- X case '-': /* SCO Xenix compatibility */
- X addflag = 0; /* don't add to MAKEFLAGS */
- X break;
- X
- X case 'd': /* show dependencies */
- X addflag = 0; /* don't add to MAKEFLAGS */
- X opts.depend++;
- X break;
- X
- X case 'D': /* display makefiles */
- X dispcount++;
- X break;
- X
- X case 'e': /* don't override environment */
- X opts.envirn = 1;
- X break;
- X
- X case 'f': /* new makefile name */
- X addflag = 0; /* don't add to MAKEFLAGS */
- X if (argc < 2)
- X usage();
- X if (flen == fmax)
- X flist = grow_list(flist, &fmax);
- X ++argv, --argc;
- X flist[flen++] = *argv;
- X
- X *argv = NULL;
- X break;
- X
- X case 'i': /* ignore errors */
- X opts.ignore = 1;
- X break;
- X
- X case 'k': /* give up on current target on error */
- X opts.keepon = 1;
- X break;
- X
- X case 'n': /* don't execute commands */
- X opts.noexec = 1;
- X break;
- X
- X case 'q': /* question mode */
- X opts.query = 1;
- X break;
- X
- X case 'r': /* don't read default.mk */
- X readdef = 0;
- X break;
- X
- X case 's': /* don't echo commands */
- X opts.silent = 1;
- X break;
- X
- X case 'S': /* Undo -k option */
- X no_k = 1;
- X break;
- X
- X case 't': /* touch files, don't build */
- X opts.touch = 1;
- X break;
- X
- X case 'W': /* What-if file is touched? */
- X if (argc < 2)
- X usage();
- X ++argv, --argc;
- X fp = add_file(*argv);
- X fp->ftime = now;
- X
- X *argv = NULL;
- X break;
- X
- X default:
- X usage(); /* never returns */
- X }
- X }
- X
- X if (addflag)
- X {
- X tfree(makeflags);
- X makeflags = tstrcat(tmf, " ");
- X }
- X
- X tfree(tmf);
- X }
- X
- X /* terminate all lists with a NULL pointer */
- X
- X tlist[tlen] = NULL;
- X flist[flen] = NULL;
- X mlist[mlen] = NULL;
- X
- X /* check for -S over-riding -k option */
- X if (no_k)
- X opts.keepon = 0;
- X
- X /* let the caller update the makeflags macro */
- X}
- X
- X
- X/*
- X * grow_list - expand the list of pointers by a factor of two
- X */
- Xchar **grow_list(list, len)
- Xchar **list;
- Xint *len;
- X{
- X int l;
- X
- X /* if list is NULL, start off with a default list */
- X
- X if (list == NULL)
- X list = (char **) talloc(((l = 1) + 1) * sizeof(char *));
- X else
- X {
- X l = *len; /* get current length */
- X
- X list = (char **) trealloc((char *) list,
- X ((l <<= 1) + 1) * sizeof(char *));
- X }
- X
- X if (list == NULL)
- X terror(1, "too many options");
- X
- X /* if we are initially allocating it, set first pointer to NULL */
- X
- X if (l == 1)
- X *list = NULL;
- X
- X *len = l; /* update current length */
- X return (list);
- X}
- X
- X
- X/*
- X * fopenp - open file in current directory or along PATH
- X */
- XFILE *fopenp(fname, type)
- Xchar *fname;
- Xchar *type;
- X{
- X int len;
- X char *fpath;
- X FILE *fd;
- X char *path;
- X char *tp;
- X
- X /* try to open file relative to current directory */
- X if ((fd = fopen(fname, type)) != NULL)
- X return (fd);
- X#ifndef MSDOS
- X /* didn't work, try home directory */
- X if ((path = getenv("HOME")) != NULL)
- X {
- X fpath = talloc(strlen(path) + strlen(fname) + 2);
- X
- X strcpy(fpath, path);
- X len = strlen(fpath) - 1;
- X
- X /* make sure there is a separator between path and filename */
- X
- X if (!strchr(FILE_SEPARATOR, fpath[len]))
- X fpath[++len] = '/';
- X
- X strcpy(&fpath[len + 1], fname); /* attach the filename */
- X fd = fopen(fpath, type);
- X tfree(fpath);
- X
- X if (fd != NULL)
- X return (fd);
- X }
- X#endif
- X /* didn't work, search along path */
- X
- X if ((path = getenv("PATH")) == NULL)
- X return (NULL);
- X
- X path = tstrcpy(path); /* allocate string and copy */
- X fpath = talloc(strlen(path) + strlen(fname) + 2);
- X
- X /* look for tokens separated by semi-colons (;) or colons (:) */
- X
- X tp = token(path, PATH_SEPARATOR, NULL);
- X while (tp != NULL)
- X {
- X strcpy(fpath, tp);
- X len = strlen(fpath) - 1;
- X
- X /* make sure there is a separator between path and filename */
- X
- X if (!strchr(FILE_SEPARATOR, fpath[len]))
- X fpath[++len] = '/';
- X
- X strcpy(&fpath[len + 1], fname); /* attach the filename */
- X if ((fd = fopen(fpath, type)) != NULL)
- X break;
- X
- X tp = token(NULL, PATH_SEPARATOR, NULL);
- X }
- X
- X tfree(path);
- X tfree(fpath);
- X
- X return (fd);
- X}
- X
- X
- X/*
- X * make - guts of the make command
- X * - make all pre-requisites, and if necessary, build target
- X *
- X * returns -1 target was already up to date w.r.t. pre-requisites
- X * 0 target has not been built
- X * 1 target is now built (and up to date)
- X */
- Xmake(targname, worry)
- Xchar *targname;
- Xint worry; /* if set, it is an error to NOT build this */
- X{
- X targptr targp;
- X fileptr *preqp;
- X int mk;
- X fileptr filep;
- X long targtime;
- X long preqtime;
- X char *dol_quest;
- X char *dq;
- X
- X mk = 0;
- X
- X /* if recorded time of file is not default, we've already built it */
- X filep = get_file(targname);
- X if (filep && filep->ftime != MAXNEGTIME)
- X return (1);
- X
- X targp = get_target(targname); /* find the target node */
- X if (targp == NULL)
- X return (default_rule(targname, NULL, worry, 0));
- X
- X /* keep actual time of current target */
- X targtime = file_time(targname, 0);
- X
- X /* must build non-existant files, even with no pre-requisites */
- X preqtime = MAXNEGTIME + 1;
- X
- X dol_quest = tstrcpy("");
- X
- X /* make all pre-requisites */
- X preqp = targp->tpreq;
- X while (preqp && *preqp)
- X {
- X mk |= make((*preqp)->fname, worry);
- X
- X /* keep track of newest pre-requisite */
- X if (preqtime < (*preqp)->ftime)
- X preqtime = (*preqp)->ftime;
- X
- X if (targtime < (*preqp)->ftime)
- X {
- X dq = tstrcat(dol_quest, (*preqp)->fname);
- X tfree(dol_quest);
- X dol_quest = tstrcat(dq, " ");
- X tfree(dq);
- X }
- X
- X /* display as necessary */
- X if (opts.depend > 1 ||
- X (opts.depend && (*preqp)->ftime > targtime))
- X {
- X display_prereq(targname, targtime, (*preqp)->fname,
- X (*preqp)->ftime);
- X }
- X
- X ++preqp;
- X }
- X
- X add_symbol("?", dol_quest, 0);
- X tfree(dol_quest);
- X
- X if (targp->tshell == NULL) /* try default rules anyway */
- X {
- X if (default_rule(targname, targp, 0, preqtime > targtime))
- X return (1);
- X return (mk);
- X }
- X else
- X if (preqtime > targtime)
- X {
- X if (opts.touch) /* won't be set when `noexec' */
- X touch_file(targname);
- X else
- X {
- X add_metas("", "", targname);
- X if (build(targp->tshell))
- X return (0);
- X }
- X
- X targp->tfile->ftime = (opts.noexec) ? now
- X : file_time(targname, 1);
- X return (1);
- X }
- X
- X targp->tfile->ftime = targtime;
- X
- X return (mk);
- X}
- X
- X
- X/*
- X * default_rule - try the .SUFFIXES when we don't have an explicit target
- X * - if `worry' is set, it is an ERROR to NOT build this target
- X * - `mustbuild' is set if make() has out-of-date prereq's
- X * but no explicit shell rules
- X */
- Xdefault_rule(targname, targetp, worry, mustbuild)
- Xchar *targname;
- Xtargptr targetp;
- Xint worry;
- Xint mustbuild;
- X{
- X targptr targp;
- X fileptr *preqp;
- X fileptr filep;
- X char *ext;
- X char *basename;
- X char *preqname;
- X long targtime;
- X long preqtime;
- X int built;
- X char suffrule[80];
- X
- X ext = strrchr(targname, '.'); /* find the extension */
- X if (ext == NULL)
- X ext = targname + strlen(targname);
- X
- X basename = tstrncpy(targname, ext - targname); /* find the base name */
- X
- X targtime = file_time(targname, 0);
- X
- X /* suffix_targ is used to (slightly) speed up this function */
- X preqp = suffix_targ ? suffix_targ->tpreq : NULL;
- X built = 0;
- X
- X while (preqp && *preqp && !built)
- X {
- X /* look for a default rule from SUFFIX to `ext' */
- X strcat(strcpy(suffrule, (*preqp)->fname), ext);
- X targp = get_target(suffrule); /* e.g. `.c.o' */
- X
- X if (targp != NULL)
- X {
- X /* found a rule; see if file exists */
- X preqname = get_preqname(targetp, (*preqp)->fname,
- X basename);
- X preqtime = file_time(preqname, 0);
- X
- X /*
- X * don't bother recursive makes unless necessary e.g.
- X * we have .c.o and .l.c, but also .l.o! we want to
- X * use .l.o if a .c file does not exist
- X */
- X if (preqtime != MAXNEGTIME || mustbuild)
- X built = make(preqname, 0);
- X
- X /* check if pre-req file exists and is newer */
- X preqtime = file_time(preqname, 0);
- X if (preqtime > targtime || (mustbuild && built))
- X {
- X if (opts.depend)
- X {
- X display_prereq(targname, targtime,
- X preqname, preqtime);
- X }
- X
- X if (opts.touch) /* won't be set when `noexec' */
- X touch_file(targname);
- X else
- X {
- X add_metas(basename, preqname, targname);
- X if (build(targp->tshell))
- X return (0);
- X }
- X built = 1;
- X }
- X else
- X if (opts.depend > 1 && preqtime != MAXNEGTIME)
- X {
- X display_prereq(targname, targtime,
- X preqname, preqtime);
- X }
- X
- X tfree(preqname);
- X }
- X
- X ++preqp; /* try next .SUFFIXES rule */
- X }
- X
- X if (!built)
- X {
- X /* didn't find anything; try the default rule */
- X targp = get_target(".DEFAULT");
- X if (targp != NULL)
- X {
- X add_metas(basename, "", targname);
- X if (build(targp->tshell))
- X return (0);
- X built = 1;
- X }
- X else
- X if (targtime == MAXNEGTIME && worry)
- X terror(1, tstrcat("Don't know how to make ", targname));
- X }
- X
- X tfree(basename);
- X
- X /* record the current file time */
- X if ((filep = get_file(targname)) != NULL)
- X {
- X filep->ftime = (built == 1 && opts.noexec) ? now
- X : file_time(targname, 1);
- X }
- X
- X return (built ? built : ((targtime == MAXNEGTIME) ? 0 : 1));
- X}
- X
- X
- X/*
- X * get_preqname - find prerequisite name from target and prerequisite suffix
- X */
- Xchar *get_preqname(targp, suffix, basename)
- Xtargptr targp;
- Xchar *suffix;
- Xchar *basename;
- X{
- X fileptr *preqp;
- X char *preqf;
- X char *basef;
- X int i;
- X
- X if (targp != NULL)
- X {
- X /* strip the directory name from the basename */
- X basef = tsplit(basename, FILE_SEPARATOR, NULL);
- X
- X /* look through prerequisite list for file with right name */
- X for (preqp = targp->tpreq; preqp && *preqp; ++preqp)
- X {
- X /* split the pre-requisite into dir and filenames */
- X preqf = tsplit((*preqp)->fname, FILE_SEPARATOR, NULL);
- X
- X /* see if the filename part matches the target */
- X for (i = 0; preqf[i] != '\0'; i++)
- X {
- X if (preqf[i] != basef[i])
- X break;
- X }
- X
- X /* if we differed only on the suffix, we're okay */
- X if (strcmp(preqf + i, suffix) == 0)
- X return (tstrcpy((*preqp)->fname));
- X }
- X#ifdef ALL_PREQS
- X /* didn't find a matching basename + suffix in the preq-list. */
- X /* look through prerequisite list for file with right suffix. */
- X for (preqp = targp->tpreq; preqp && *preqp; ++preqp)
- X {
- X preqf = strrchr((*preqp)->fname, '.');
- X if (preqf == NULL)
- X continue;
- X
- X /* take the first file which has right suffix */
- X if (strcmp(suffix, preqf) == 0)
- X return (tstrcpy((*preqp)->fname));
- X }
- X#endif /* ALL_PREQS */
- X }
- X
- X /* didn't find one, so try forming one using basename + suffix */
- X
- X return (tstrcat(basename, suffix));
- X}
- X
- X
- X/*
- X * add_metas - add symbols for $*, $< and $@
- X */
- Xadd_metas(basename, preqname, targname)
- Xchar *basename;
- Xchar *preqname;
- Xchar *targname;
- X{
- X /* $* is the basename */
- X add_symbol("*", basename, 0);
- X split_meta("*", basename);
- X
- X add_symbol("<", preqname, 0);
- X split_meta("<", preqname);
- X
- X add_symbol("@", targname, 0);
- X split_meta("@", targname);
- X}
- X
- X
- X/*
- X * split_meta - split a metasymbol into Directory and File parts
- X */
- Xsplit_meta(sym, name)
- Xchar *sym;
- Xchar *name;
- X{
- X char *dname;
- X char *dsym;
- X char *fsym;
- X
- X /* construct the macro names (e.g. $(*D), $(@F)) */
- X dsym = tstrcat(sym, "D");
- X fsym = tstrcat(sym, "F");
- X
- X add_symbol(fsym, tsplit(name, FILE_SEPARATOR, &dname), 0);
- X
- X if (dname == NULL)
- X add_symbol(dsym, ".", 0);
- X else
- X {
- X add_symbol(dsym, dname, 0);
- X tfree(dname);
- X }
- X
- X tfree(dsym);
- X tfree(fsym);
- X}
- X
- X
- X/*
- X * touch_file - set the MODIFICATION time of the file to NOW
- X */
- Xtouch_file(targname)
- Xchar *targname;
- X{
- X int handle;
- X#ifndef MSDOS
- X time_t timep[2];
- X
- X time(&timep[0]);
- X timep[1] = timep[0];
- X handle = utime(targname, timep);
- X#else
- X handle = utime(targname, NULL);
- X#endif
- X fputs("touch ", stdout);
- X puts(targname);
- X
- X if (handle == 0)
- X return;
- X
- X /* create the file, if it did not exist */
- X if (errno == ENOENT)
- X {
- X handle = open(targname, O_CREAT | O_TRUNC, S_IWRITE);
- X if (handle != -1)
- X {
- X close(handle);
- X return;
- X }
- X }
- X
- X perror("touch");
- X exit(1);
- X}
- X
- Xdisplay_prereq(targname, targtime, preqname, preqtime)
- Xchar *targname;
- Xlong targtime;
- Xchar *preqname;
- Xlong preqtime;
- X{
- X#ifdef MSDOS
- X char chtime[10];
- X
- X fputs(targname, stdout);
- X fputs(" (", stdout);
- X fputs(ltoa(targtime, chtime, 16), stdout);
- X fputs((targtime <= preqtime) ? ") older than " : ") newer than ", stdout);
- X fputs(preqname, stdout);
- X fputs(" (", stdout);
- X fputs(ltoa(preqtime, chtime, 16), stdout);
- X puts(")");
- X#else
- X printf("%s (%08lx) %s than %s (%08lx)\n",
- X targname, targtime,
- X (targtime < preqtime) ? "older" : "newer",
- X preqname, preqtime);
- X#endif
- X}
- X
- X
- Xlong file_time(fname, built)
- Xchar *fname;
- Xint built;
- X{
- X struct stat sbuf;
- X
- X /*
- X * if the file is supposedly built, but still does not exists, just
- X * fake it by returning the current time.
- X */
- X if (stat(fname, &sbuf) != 0)
- X return (built ? now : MAXNEGTIME);
- X return (sbuf.st_mtime);
- X}
- X
- X
- Xusage()
- X{
- X puts("make [-f file] [-dDiknqrsStWb-] [target ...] [macro=value ...]");
- X exit(1);
- X}
- END_OF_FILE
- if test 18624 -ne `wc -c <'make.c'`; then
- echo shar: \"'make.c'\" unpacked with wrong size!
- fi
- # end of 'make.c'
- fi
- if test -f 'make.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'make.doc'\"
- else
- echo shar: Extracting \"'make.doc'\" \(19978 characters\)
- sed "s/^X//" >'make.doc' <<'END_OF_FILE'
- XNAME
- X make - maintain, update, and reconstruct groups of programs
- X
- XSYNOPSIS
- X make [-f file] [-dDeiknqrsStWb-] [target...] [macro=value ...]
- X
- XDESCRIPTION
- X MAKE takes a file of dependencies (a 'makefile') and decides what
- X commands have to be executed to bring the files up to date. These
- X commands are either executed directly from MAKE or written to the
- X standard output without executing them.
- X
- X If no makefile is specified with a -f option, MAKE reads a file
- X named `makefile', if it exists.
- X
- X If no target is specified on the command line, MAKE uses the first
- X target defined in the first makefile.
- X
- XOPTIONS
- X -f makefile
- X Use the description file `makefile'. A - as the makefile
- X argument denotes the standard input.
- X
- X -d Display the reasons why MAKE chooses to rebuild a target. All
- X dependencies which are newer are displayed
- X
- X -dd Display the dependency checks in more detail. Dependencies
- X which are older are displayed, as well as newer.
- X
- X -D Display the text of the makefiles as read in.
- X
- X -DD Display the text of the makefiles and `default.mk'.
- X
- X -e Let environment variables override macro definitions from
- X makefiles. Normally, makefile macros override environment
- X variables. Command line macro definitions always override both
- X environment variables and makefile macros definitions.
- X
- X -i Ignore error codes returned by commands. This is equivalent to
- X the special target .IGNORE:.
- X
- X -k When a nonzero error status is returned by a command, abandon
- X work on the current target, but continue with other branches
- X that do not depend on this target.
- X
- X -n No execution mode. Print commands, but do not execute them.
- X Even lines beginning with an @ are printed. However, if a
- X command line is an invocation of MAKE, that line is always
- X executed.
- X
- X -q Question mode. MAKE returns a zero or non-zero status code,
- X depending on whether or not the target file is up to date.
- X
- X -r Do not read in the default file `default.mk'.
- X
- X -s Silent mode. Do not print command lines before executing them.
- X This is equivalent to the special target .SILENT:.
- X
- X -S Undo the effect of the -k option. Stop processing when a
- X non-zero exit status is returned by a command.
- X
- X -t Touch the target files, bringing them up to date, rather than
- X performing the rules to reconstruct them.
- X
- X -W target
- X Perform the make as if this target has a modification time of
- X "right now". This is the "What If?" option.
- X
- X -b This option is accepted and ignored. It allows compatibility
- X with older makefiles (and scripts).
- X
- X -- This option is accepted and ignored. It allows compatibility
- X with SCO Xenix which requires -$(MAKEFLAGS). This version of
- X make includes a '-' within $(MAKEFLAGS).
- X
- X macro=value
- X Macro definition. This definition remains fixed for the MAKE
- X invocation. It overrides any regular definitions for the
- X specified macro within the makefiles and from the environment.
- X It is inherited by subordinate MAKE's but act as an environment
- X variable for these. That is, depending on the -e setting, it
- X may be overridden by a makefile definition.
- X
- XUSAGE
- X Makefiles
- X The first makefile read is `default.mk', which can be located any-
- X where along the PATH. It typically contains predefined macros and
- X implicit rules. For non-DOS systems (e.g. Unix), it is searched
- X for in the current directory, then in the users home directory, and
- X finally along the PATH.
- X
- X The default name of the makefile is `makefile' in the current
- X directory. If this file is not found on a non-DOS system, the file
- X `Makefile' is then used as the default. Alternate makefiles can be
- X specified using one or more '-f' options on the command line.
- X Multiple '-f's act as the concatenation of all the makefiles in a
- X left-to-right order.
- X
- X The makefile(s) may contain a mixture of comment lines, macro
- X definitions, include lines, and target lines. Lines may be
- X continued across input lines by escaping the NEWLINE with a
- X backslash (\).
- X
- X Anything after a "#" is considered to be a comment, and is stripped
- X from the line, including spaces immediately before the "#. If the
- X "#" is inside a quoted string, it is not treated as a comment.
- X Completely blank lines are ignored.
- X
- X An include line is used to include the text of another makefile.
- X It consists of the word "include" left justified, followed by
- X spaces, and followed by the name of the file that is to be included
- X at this line. Macros in the name of the included file are expanded
- X before the file is included. Include files may be nested.
- X
- X Macros
- X Macros have the form `WORD = text and more text'. The WORD need
- X not be uppercase, but this is an accepted standard. Later lines
- X which contain $(WORD) or ${WORD} will have this replaced by `text
- X and more text'. If the macro name is a single character, the
- X parentheses are optional. Note that the expansion is done
- X recursively, so the body of a macro may contain other macro
- X invocations.
- X
- X e.g. FLINTSTONES = wilma and fred
- X RUBBLES = barney and betty
- X BEDROCK = $(FLINTSTONES) and $(RUBBLES)
- X
- X `$(BEDROCK)' becomes `wilma and fred and barney and betty'
- X
- X Also note that whitespace around the equal sign is not relevant
- X when defining a macro. The following four macro definitions are
- X all equivalent:
- X
- X MACRO = body
- X MACRO= body
- X MACRO =body
- X MACRO=body
- X
- X Macros may be added to by using the `+=' notation. Thus
- X
- X FLINTSTONES += and pebbles and dino
- X
- X would be (given the examples above) the same as
- X
- X FLINTSTONES = wilma and fred and pebbles and dino
- X
- X Special Macros
- X MAKE
- X This normally has the value "make". Any line which invokes
- X MAKE temporarily overrides the -n option, just for the duration
- X of the one line. This allows nested invocations of MAKE to be
- X tested with the -n option.
- X
- X MAKEFLAGS
- X This macro has the set of options provided to MAKE as its
- X value. If this is set as an environment variable, the set of
- X options is processed before any command line options. This
- X macro may be explicitly passed to nested MAKEs, but it is also
- X available to these invocations as an environment variable. The
- X -f and -d flags are not recorded in this macro.
- X
- X SUFFIXES
- X This contains the default list of suffixes supplied to the
- X special target .SUFFIXES:. It is not sufficient to simply
- X change this macro in order to change the .SUFFIXES: list. That
- X target must be specified in your makefile.
- X
- X SHELLCMD
- X This contains the default list of commands which are local to
- X the SHELL. If a rule is an invocation of one of these
- X commands, a SHELL is automatically spawned to handle it.
- X
- X $ This macro translates to a dollar sign. Thus you can use "$$"
- X in the makefile to represent a single "$".
- X
- X There are several dynamically maintained macros that are useful as
- X abbreviations within rules. It is best not to define them
- X explicitly.
- X
- X $* The basename of the current target.
- X
- X $< The name of the current dependency file.
- X
- X $@ The name of the current target.
- X
- X $? The names of dependents which are younger than the target.
- X
- X The $< and $* macros are normally used for implicit rules. They
- X may be unreliable when used within explicit target command lines.
- X These may be suffixed with D and F, to specify the Directory and
- X Filename components (e.g. ${*D}, ${@F}). If there is no directory
- X in the name, "." is supplied.
- X
- X Targets
- X A target entry in the makefile has the following format:
- X
- X target ... : [dependency ...] [; rule]
- X [rule]
- X ...
- X
- X Any line which does not have leading whitespace (other than macro
- X definitions) is a `target' line. Target lines consist of one or
- X more filenames (or macros which expand into same) called targets,
- X followed by a colon (:). The ':' is followed by a list of
- X dependent files. The dependency list may be terminated with a
- X semicolon (;) which may be followed by a rule or shell command.
- X
- X Special allowance is made on MSDOS for the colons which are needed
- X to specify files on other drives, so for example, the following
- X will work as intended:
- X
- X c:foo.bar : a:fee.ber
- X
- X If a target is named in more than one target line, the dependencies
- X and rules are added to form the target's complete dependency list
- X and rule list.
- X
- X The dependents are ones from which a target is constructed. They
- X in turn may be targets of other dependents. In general, for a
- X particular target file, each of its dependent files is `made', to
- X make sure that each is up to date with respect to it's dependents.
- X
- X The modification time of the target is compared to the modification
- X times of each dependent file. If the target is older, one or more
- X of the dependents have changed, so the target must be constructed.
- X Of course, this checking is done recursively, so that all
- X dependents of dependents of dependents of ... are up to date.
- X
- X To reconstruct a target, MAKE expands macros, strips off initial
- X whitespace, and either executes the rules directly, or passes each
- X to a shell or COMMAND.COM for execution.
- X
- X For target lines, macros are expanded on input. All other lines
- X have macro expansion delayed until absolutely required.
- X
- X Special Targets
- X .DEFAULT:
- X The rule for this target is used to process a target when there
- X is no other entry for it, and no implicit rule for building it.
- X MAKE ignores all dependencies for this target.
- X
- X .DONE:
- X This target and its dependencies are processed after all other
- X targets are built.
- X
- X .IGNORE:
- X Non-zero error codes returned from commands are ignored.
- X Encountering this in a makefile is the same as specifying -i on
- X the command line.
- X
- X .INIT:
- X This target and its dependencies are processed before any other
- X targets are processed.
- X
- X .SILENT:
- X Commands are not echoed before executing them. Encountering
- X this in a makefile is the same as specifying -s on the command
- X line.
- X
- X .SUFFIXES:
- X The suffixes list for selecting implicit rules. Specifying
- X this target with dependents adds these to the end of the
- X suffixes list. Specifying it with no dependents clears the
- X list. In order to add your own dependents to the head of the
- X list, you could enter:
- X
- X .SUFFIXES:
- X .SUFFIXES: .abc $(SUFFIXES)
- X
- X Rules
- X A line in a makefile that starts with a TAB or SPACE is a shell
- X line or rule. This line is associated with the most recently
- X preceding dependency line. A sequence of these may be associated
- X with a single dependency line. When a target is out of date with
- X respect to a dependent, the sequence of commands is executed.
- X Shell lines may have any combination of the following characters to
- X the left of the command:
- X
- X @ will not echo the command line, except if -n is used.
- X
- X - MAKE will ignore the exit code of the command, i.e. the
- X ERRORLEVEL of MSDOS. Without this, MAKE terminates when a
- X nonzero exit code is returned.
- X
- X + MAKE will use a shell or COMMAND.COM to execute the command.
- X
- X If the '+' is not attached to a shell line, but the command is a
- X DOS command or if redirection is used (<, |, >), the shell line is
- X passed to COMMAND.COM anyway. For Unix, redirection, backquote (`)
- X parentheses and variables ($vname) force the use of a shell.
- X
- X For DOS, inline stdin (<<) operator is emulated with a temporary
- X file. That is, subsequent commands are written to a temporary
- X file, and the name of the temporary file is placed in the command
- X line. For example, if you want to link a number of objects
- X together, you can have a rule such as
- X
- X link $(OBJS),$(NAME),$(LDFLAGS),$(LIBS)
- X
- X If the resulting command line (after expansion) is greater than
- X 128, you can specify in the following manner.
- X
- X link @<<END_OF_LINK
- X $(OBJS)
- X $(NAME)
- X $(LDFLAGS)
- X $(LIBS)
- X END_OF_LINK
- X
- X The four lines between the tags (END_OF_LINK) are written to a
- X temporary file (e.g. "\mk2"), and the command line is rewritten as
- X "link @\mk2".
- X
- X The rules for redirection and tags are as follows:
- X
- X 1) If the redirector (<<) is immediately followed by some text,
- X the text is used as the tag. E.g. "<<END_OF_LINK".
- X
- X 2) If the redirector is not immediately followed by some text,
- X the next token is used as the tag. E.g. "<< END_OF_LINK".
- X
- X 3) If the redirector is the last token on a line, there is no
- X tag.
- X
- X 4) Lines immediately following the command are written to a
- X temporary file, until a line beginning with the tag is
- X encountered or until the end of the current set of rules.
- X
- X The following are all equivalent.
- X
- X link @<< link @<<END_OF_LINK link @<<END_OF_LINK
- X $(OBJS) $(OBJS) $(OBJS)
- X $(PROG) $(PROG) $(PROG)
- X $(LDFLAGS) $(LDFLAGS) $(LDFLAGS)
- X $(LIBS) $(LIBS) $(LIBS)
- X END_OF_LINK
- X
- X Implicit Rules
- X Implicit rules are intimately tied to the .SUFFIXES: special
- X target. Each entry in the .SUFFIXES defines an extension to a
- X filename which may be used to build another file. The implicit
- X rules then define how to actually build one file from another.
- X These files are related, in that they must share a common basename,
- X but have different extensions.
- X
- X If a file that is being made does not have an explicit target line,
- X an implicit rule is looked for. Each entry in the .SUFFIXES: list
- X is combined with the extension of the target, to get the name of an
- X implicit target. If this target exists, it gives the rules used to
- X transform a file with the dependent extension to the target file.
- X Any dependents of the implicit target are ignored.
- X
- X In the following example, the .SUFFIXES: list is .c .y .l, and the
- X target file is fred.o which does not have a target line. An
- X implicit rule target `.c.o' is constructed and searched for. If it
- X does not exist, the next suffix is tried. If the implicit rule
- X target does exist, MAKE looks for a file `fred.c'. If this file
- X does not exist, the next extension is tried. If `fred.c' does
- X exist, then the associated rules are executed to create fred.o from
- X fred.c, presumably invoking the C compiler.
- X
- X If the next extension must be tried, MAKE reiterates the above with
- X target `.y.o' and a file named `fred.y', and potentially with
- X `.l.o' and `fred.l'.
- X
- X If a file that is being made has an explicit target, but no rules,
- X a similar search is made for implicit rules. Each entry in the
- X .SUFFIXES: list is combined with the extension of the target, to
- X get the name of an implicit target. If such a target exists, then
- X the list of dependents is searched for a file with the correct
- X extension, and the implicit rules are invoked to create the target.
- X
- XEXAMPLES
- X This makefile says that pgm.exe depends on two files a.obj and
- X b.obj, and that they in turn depend on their corresponding source
- X files (a.c and b.c) along with the common file incl.h.
- X
- X pgm.exe: a.obj b.obj
- X $(CC) a.obj b.obj -o $@
- X
- X a.obj: incl.h a.c
- X $(CC) -c a.c
- X
- X b.obj: incl.h b.c
- X $(CC) -c b.c
- X
- X The following makefile uses implicit rules to express the same
- X dependencies.
- X
- X pgm.exe: a.obj b.obj
- X $(CC) a.obj b.obj -o $@
- X
- X a.obj b.obj: incl.h
- X
- X This final makefile uses implicit rules to create targets with
- X dependencies in a different directory. Note: this cannot be done
- X with standard Unix make.
- X
- X pgm.exe: a.obj b.obj
- X $(CC) a.obj b.obj -o $@
- X
- X a.obj: incl.h ../a.c
- X
- X b.obj: incl.h ../b.c
- X
- XFILES
- X makefile Current version(s) of make description file.
- X Makefile Alternative to makefile, for Unix.
- X default.mk Default file for user-defined targets, macros,
- X and implicit rules.
- X
- XDIAGNOSTICS
- X MAKE returns an exit status of 1 when it halts as a result of an
- X error. Otherwise it returns an exit status of 0.
- X
- X Badly formed macro
- X A macro definition has been encountered which has incorrect
- X syntax. Most likely, the name is missing.
- X
- X cannot open file
- X The makefile indicated in an include directive was not found or
- X was not accessible.
- X
- X Don't know how to make target
- X There is no makefile entry for target, none of MAKE's implicit
- X rules apply, and there is no .DEFAULT: rule.
- X
- X Improper Macro.
- X An error has occurred during macro expansion. The most likely
- X error is a missing closing bracket.
- X
- X Macro too long (limit 100 chars):
- X A macro name is too long for the internal buffer. Try shortening
- X it to 100 characters or less.
- X
- X rules must be after target
- X A makefile syntax error, where a line beginning with a SPACE or
- X TAB has been encountered before a target line.
- X
- X too many options
- X MAKE has run out of allocated space while processing command
- X line options or a target list.
- X
- X Too many rules defined for target
- X A target occurs multiple times, and each time has rules. A
- X target may only have one set of rules.
- X
- X Unexpected end of line seen
- X A target line without a colon has been encountered.
- X
- XAUTHOR
- X Greg Yachuk Informix Software Inc., Menlo Park, CA 92025
- X greggy@informix.com | {uunet,pyramid}!infmx!greggy (415) 926-6300
- X
- X Parts of this program are based on the work by Larry Campbell of
- X DEC, Mike Hickey of University of DC, and by Dan Grayson.
- X
- X Some of this documentation is based on text written by Jeffrey
- X Spidle of Iowa State University and by Dan Grayson.
- X
- X Some of the formatting of this documentation follows the example of
- X Sun Microsystems for their UNIX 4.2 Release.
- X
- XBUGS
- X The -n does not always correctly identify the targets which need to
- X be made. It never misses required makes, but sometimes includes
- X unrequired makes. It also incorrectly sets up the $? macro in
- X these circumstances. This does not happen during full execution.
- X
- X MAKE allows spaces as well as TABs to introduce shell command
- X lines.
- X
- X Target lines cannot use the double colon (::) syntax.
- X
- X Once a dependency is made, MAKE assumes that the dependency file is
- X present for the remainder of the run. If a rule subsequently
- X removes that file and future targets depend on it's existence,
- X unexpected errors may result.
- X
- X Sometimes MAKE gets confused when searching for implicit rules, and
- X uses several rules instead of a single rule. For example, the two
- X rules .c.o and .l.c may be used, rather than the more direct .l.o
- X rule.
- X
- X If a number of command line flags are run together, and contains
- X either `f' or `d', the whole set of flags is dropped from
- X MAKEFLAGS.
- X
- X The following flags are NOT supported:
- X
- X -p Print out the compete set of macro definitions and target
- X descriptions.
- X
- X -P Report dependencies recursively to show the entire dependency
- X hierarchy, without rebuilding any targets.
- X
- X The following special targets are NOT supported:
- X
- X .KEEP_STATE:
- X .MAKE_VERSION:
- X .PRECIOUS:
- X .SCCS_GET:
- END_OF_FILE
- if test 19978 -ne `wc -c <'make.doc'`; then
- echo shar: \"'make.doc'\" unpacked with wrong size!
- fi
- # end of 'make.doc'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-